package com.kamistoat.ruoyi.ruoyimoduleslocalfile.service.impl;

import com.kamistoat.ruoyi.ruoyimoduleslocalfile.config.MinioConfig;
import com.kamistoat.ruoyi.ruoyimoduleslocalfile.service.SysFileService;
import com.kamistoat.ruoyi.ruoyimoduleslocalfile.utils.FileUploadUtils;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

/**
 * 使用 Minio框架实现文件持久化。
 * P.S. 使用Minio框架时，LocalResourcesConfig配置并不生效
 */
@Service("MinioSysFileServiceImpl")
public class MinioSysFileServiceImpl implements SysFileService {

    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioConfig minioConfig;

    private final String minioURL = minioConfig.getMinmoUrl();
    private final String minioAccessKey = minioConfig.getAccessKey();
    private final String minioSecretKey = minioConfig.getSecretKey();
    private final String bucketName = minioConfig.getBucketName();

    /**
     * 文件上传接口
     *
     * @param multipartFile multipartFile文件
     * @return 持久化成功后的文件访问地址。将由 文件服务器Ip/文件资源标识符/文件在根目录下的绝对路径 组成
     * @throws Exception
     */
    @Override
    public String uploadFile(MultipartFile multipartFile) throws Exception {
        // 获取编码后的根目录下文件名
        String codingFileName = FileUploadUtils.extractFilename(multipartFile);

        // 使用 Minion的构造器
        PutObjectArgs minioArgs = PutObjectArgs.builder()
                // 桶名称
                .bucket(bucketName)
                // 文件名称
                .object(codingFileName)
                // 持久化的内容。以 InputStream的形式给出，可以自定义截取InputStream的大小以及是否分片
                .stream(multipartFile.getInputStream(), multipartFile.getSize(), -1)
                // 文件内容类型
                .contentType(multipartFile.getContentType())
                .build();

        // 使用 MinioClient.putObject() 进行持久化
        minioClient.putObject(minioArgs);

        // Minion和OSS是类似的，也是 url+桶名 直接精确定位到桶(即根目录)，然后再根据文件路径去定位文件
        // 因此不需要加上 资源文件标识符/statics，实际上加上反而是错的，因为请求是发给minio，又不是发给这
        return minioURL + "/" + bucketName + "/" + codingFileName;
    }
}
